package com.jiantong.web.open.app.lawEnforcing;

import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.lawEnforcing.dto.CasesInformationDto;
import com.jiantong.lawEnforcing.model.CasesInformation;
import com.jiantong.lawEnforcing.service.BorrowRecordService;
import com.jiantong.lawEnforcing.service.CasesInformationService;
import com.jiantong.web.core.enums.ExceptionCode;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.PageInfo;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Strings;
import org.joda.time.DateTime;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 案件信息
 * Created by mz03 on 2017/8/15.
 */
@Slf4j
@OpenBean
public class CasesInformationApis {

    @RpcConsumer
    private CasesInformationService casesInformationService;
    @RpcConsumer
    private BorrowRecordService borrowRecordService;

    /**
     * 根据id查询一条信息
     * @param id
     * @return
     */
    @OpenMethod(
            key = "find.casesInformation.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public CasesInformation findById(Long id){
        Response<CasesInformation> response = casesInformationService.finById(id);
        if (!response.isSuccess()){
            log.error("failed to find casesInformation read by id = {}, cause : {}", id, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    /**
     * 创建一条信息
     * @param casesInformation
     * @return
     */
    @OpenMethod(
            key = "create.casesInformation",
            paramNames = {"casesInformation"},
            httpMethods = RequestMethod.POST
    )
    public Long create(CasesInformation casesInformation){
        Response<Long> response = casesInformationService.create(casesInformation);
        if(!response.isSuccess()){
            log.error("failed to create casesInformation read by casesInformation = {}, cause : {}", casesInformation, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    /**
     * 更新单据
     * @param casesInformation
     * @return
     */
    @OpenMethod(
            key = "update.casesInformation",
            paramNames = {"casesInformation"},
            httpMethods = RequestMethod.PUT
    )
    public Boolean update(CasesInformation casesInformation){
        if(casesInformation.getId() == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "id should be not null");
        }
        Response<Boolean> response = casesInformationService.update(casesInformation);
        if(!response.isSuccess()){
            log.error("failed to update casesInformation");
            throw new OPServerException(ExceptionCode.DATA_UPDATE_FAIL.value(), "failed to update casesInformation");
        }
        return response.getResult();
    }


    /**
     * 根据当前登录人查找
     * @param pageNo
     * @param pageSize
     * @param statusList 状态list
     * @param cause_action 案由
     * @param parties_type 案件类型
     * @param parties_name 个人姓名/单位名称
     * @param cases_number 案件编号,案件的外码,包含案件的地区信息
     * @param cases_source 案件来源
     * @param cause_affirm_date 案件定性时间
     * @param cause_end_date 案件完结时间
     * @param enforcement_name 执法人名字
     * @return
     */
    @OpenMethod(
            key = "find.paging.casesInformation",
            paramNames =
                    {"pageNo","pageSize","statusList","cause_action","parties_type","parties_name","cases_number","cases_source","cause_affirm_date","cause_end_date","enforcement_name","role"},
            httpMethods = RequestMethod.GET
    )
    public Paging<CasesInformation> pagingCasesInformation(
            Integer pageNo,
            Integer pageSize,
            List<Integer> statusList,
            String cause_action,
            Integer parties_type,
            String parties_name,
            String cases_number,
            Integer cases_source,
            String cause_affirm_date,
            String cause_end_date,
            String enforcement_name,
            Integer role
    ){

        Date start = null;
        if (!Strings.isNullOrEmpty(cause_affirm_date)) {
            start = DateTime.parse(cause_affirm_date).toDate();
        }

        Date end = null;
        if (!Strings.isNullOrEmpty(cause_end_date)) {
            end = DateTime.parse(cause_end_date).toDate();
        }

        PageInfo pageInfo = new PageInfo(pageNo,pageSize);
        Map<String, Object> criteria = Maps.newHashMap();

        if(statusList != null){
            criteria.put("status_list",statusList);
        }
        if(statusList != null){
            criteria.put("cause_action",cause_action);
        }
        if(parties_type != null){
            criteria.put("parties_type",parties_type);
        }
        if(parties_type != null){
            criteria.put("name",parties_name);
        }
        if(parties_name != null){
            criteria.put("cases_number",cases_number);
        }
        if(parties_name != null){
            criteria.put("cases_source",cases_source);
        }
        if(parties_name != null){
            criteria.put("cause_affirm_date",start);
        }
        if(parties_name != null){
            criteria.put("cause_end_date",end);
        }
        if(parties_name != null){
            criteria.put("enforcement_name",enforcement_name);
        }


        //加入当前登录人身份
        Long userId =  UserUtil.getUserId();
        if (userId != null) {
            criteria.put("designate_id", userId);
        }
        if (role.equals(13)) {
            criteria.put("designate_id",null);
        }
        Response<Paging<CasesInformation>> pagingResponse = casesInformationService.pagingByStatus(pageInfo.getOffset(),pageInfo.getLimit(), criteria);
        if(!pagingResponse.isSuccess()){
            log.error("failed to find paging casesInformation status {}, cause : {}", statusList, pagingResponse.getError());
            throw new OPServerException(pagingResponse.getError());
        }
        return pagingResponse.getResult();
    }


    /**
     * 查询全部案件,当前登录人组成dto,用来显示文书以及此文书当前登录人是否可以查看.
     */
    @OpenMethod(
            key = "find.paging.all.casesInformationDto",
            paramNames =
                    {"pageNo","pageSize","statusList","cause_action","parties_type","parties_name","cases_number","cases_source","cause_affirm_date","cause_end_date","enforcement_name"},
            httpMethods = RequestMethod.GET
    )
    public Paging<CasesInformationDto> pagingCasesInformationByUser(
            Integer pageNo,
            Integer pageSize,
            List<Integer> statusList,
            String cause_action,
            Integer parties_type,
            String parties_name,
            String cases_number,
            Integer cases_source,
            String cause_affirm_date,
            String cause_end_date,
            String enforcement_name
    ){
        Date start = null;
        if (!Strings.isNullOrEmpty(cause_affirm_date)) {
            start = DateTime.parse(cause_affirm_date).toDate();
        }

        Date end = null;
        if (!Strings.isNullOrEmpty(cause_end_date)) {
            end = DateTime.parse(cause_end_date).toDate();
        }

        PageInfo pageInfo = new PageInfo(pageNo,pageSize);
        Map<String, Object> criteria = Maps.newHashMap();

        if(statusList != null){
            criteria.put("status_list",statusList);
        }
        if(statusList != null){
            criteria.put("cause_action",cause_action);
        }
        if(parties_type != null){
            criteria.put("parties_type",parties_type);
        }
        if(parties_type != null){
            criteria.put("name",parties_name);
        }
        if(parties_name != null){
            criteria.put("cases_number",cases_number);
        }
        if(parties_name != null){
            criteria.put("cases_source",cases_source);
        }
        if(parties_name != null){
            criteria.put("cause_affirm_date",start);
        }
        if(parties_name != null){
            criteria.put("cause_end_date",end);
        }
        if(parties_name != null){
            criteria.put("enforcement_name",enforcement_name);
        }

        Response<Paging<CasesInformation>> pagingResponse = casesInformationService.pagingByStatus(pageInfo.getOffset(),pageInfo.getLimit(), criteria);
        if(!pagingResponse.isSuccess()){
            log.error("failed to find paging casesInformation status {}, cause : {}", statusList, pagingResponse.getError());
            throw new OPServerException(pagingResponse.getError());
        }

        //查到当前登录人可以查看的案件ids
        List<Long> listOk; //可以查看的案件id
        List<Long> listNo; //不能查看的案件id
        List<Long> listWait; //等待审批的案件id

        Long borrower_id = UserUtil.getUserId();
        Map<String, Object> map = Maps.newHashMap();
        if (borrower_id != null) {
            map.put("borrower_id", borrower_id);
        }
        map.put("status", 1);
        Response<List<Long>> responseOk =  borrowRecordService.findByStatus(map);
        if (!responseOk.isSuccess()) {
            log.error("failed to find casesIds by status {}, cause : {}", 1, responseOk.getError());
            throw new OPServerException(responseOk.getError());
        }
        listOk = responseOk.getResult();//得到可以查看的案件id

        if(map.containsKey("status")){
            map.put("status", 2);
        }
        Response<List<Long>> responseNo =  borrowRecordService.findByStatus(map);
        if (!responseNo.isSuccess()) {
            log.error("failed to find casesIds by status {}, cause : {}", 2, responseNo.getError());
            throw new OPServerException(responseNo.getError());
        }
        listNo = responseNo.getResult();//得到不可以查看的案件id

        if(map.containsKey("status")){
            map.put("status", 3);
        }
        Response<List<Long>> responseWait =  borrowRecordService.findByStatus(map);
        if (!responseWait.isSuccess()) {
            log.error("failed to find casesIds by status {}, cause : {}", 3, responseNo.getError());
            throw new OPServerException(responseNo.getError());
        }
        listWait = responseWait.getResult();


        Paging<CasesInformation> casesInformationPaging = pagingResponse.getResult();//查到的案件(文书)信息
        List<CasesInformation> list = casesInformationPaging.getData();
        //根据listOk和listNo casesInformationPaging 组一个dto
        List<CasesInformationDto> casesInformationDtoList = new ArrayList<>();
        for (CasesInformation casesInformation : list) {
            CasesInformationDto casesInformationDto = new CasesInformationDto();
            casesInformationDto.setCasesInformation(casesInformation);
            //判断给文书id在那个列表list中
            if (listOk!=null&&listOk.contains(casesInformation.getId())){
                casesInformationDto.setWhether(1);//已申请
            }else if (listNo!=null&&listNo.contains(casesInformation.getId())){
                casesInformationDto.setWhether(2);//可以查看
            }else if (listWait!=null&&listWait.contains(casesInformation.getId())){
                casesInformationDto.setWhether(3);//不可以查看
            } else {
                casesInformationDto.setWhether(0);//未申请
            }
            casesInformationDtoList.add(casesInformationDto);
        }
        Paging<CasesInformationDto> paging = new Paging<>();
        paging.setTotal(casesInformationPaging.getTotal());
        paging.setData(casesInformationDtoList);

        return paging;
    }



    /**
     * 根据状态列表和案由查询案件信息
     * @param pageNo
     * @param pageSize
     * @param statusList
     * @param casesInformation
     * @return
     */
    @OpenMethod(
            key = "find.paging.by.casesInformation",
            paramNames = {"pageNo","pageSize","statusList","casesInformation"},
            httpMethods = RequestMethod.GET
    )
    public Paging<CasesInformation> pagingByCasesInformation(
            Integer pageNo,
            Integer pageSize,
            List<Integer> statusList,
            CasesInformation casesInformation
    ){
        Response<Paging<CasesInformation>> pagingResponse = casesInformationService.pagingByCasesInformation(pageNo,pageSize,statusList,casesInformation);
        if(!pagingResponse.isSuccess()){
            log.error("failed to find paging casesInformation status {}, cause : {}", statusList, pagingResponse.getError());
            throw new OPServerException(pagingResponse.getError());
        }
        return pagingResponse.getResult();
    }

    /**
     * 统计查询, 根据条件查询出来 一个数据结构案件类型占比图
     */
    @OpenMethod(
            key = "find.casesSource.count",
            httpMethods = RequestMethod.GET
    )
    public Map<Integer,Integer> countByCasesSource(){
        Response<List<Map<String,Integer>>>  response = casesInformationService.countByCasesSource();
        if(!response.isSuccess()){
            log.error("failed to find countByCasesSource status {}, cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }
        List<Map<String,Integer>> list = response.getResult();
        Map<Integer,Integer> map = Maps.newHashMap();
        for (Map<String,Integer> map1:list) {
            map.put(map1.get("cases_source"),map1.get("amount"));
        }
        return map;
    }

    /**
     * 案件类型占比图
     */
    @OpenMethod(
            key = "find.casesType.count",
            httpMethods = RequestMethod.GET
    )
    public Map<Integer,Integer> countByCasesType(){
        Response<List<Map<String,Integer>>>  response = casesInformationService.countByCasesType();
        if(!response.isSuccess()){
            log.error("failed to find countByCasesType status {}, cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }
        List<Map<String,Integer>> list = response.getResult();
        Map<Integer,Integer> map = Maps.newHashMap();
        for (Map<String,Integer> map1:list) {
            map.put(map1.get("cases_type"),map1.get("amount"));
        }
        return map;
    }


}

